package fr.generali.accueilclient.gwt.client.ui.components.section;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;

public class SectionGroup {

    private final Set<Section> sections = new HashSet<Section>();

    private final Map<Section, List<ValueChangeHandler<Boolean>>> handlerMap =
                    new HashMap<Section, List<ValueChangeHandler<Boolean>>>();

    public void addSection(Section section) {
        sections.add(section);
        section.addActionLinkClickHandler(new SectionClickHandler(section));
    }

    public void addSections(Section... sectionsToAdd) {
        for (Section section : sectionsToAdd) {
            addSection(section);
        }
    }

    private class SectionClickHandler implements ClickHandler {

        private Section clickedSection;

        public SectionClickHandler(Section clickedSection) {
            this.clickedSection = clickedSection;
        }

        @Override
        public void onClick(ClickEvent event) {
            showSection(clickedSection);
        }

    }

    public void showAll() {
        for (Section section : sections) {
            section.show();
        }
        for (Section section : sections) {
            callHandlers(section, true);
        }
    }

    public void showAllActionLink() {
        for (Section section : sections) {
            section.showActionLink();
        }
    }

    public void showSection(Section sectionToShow) {
        for (Section section : sections) {
            if (section.equals(sectionToShow)) {
                section.show();
            } else {
                section.hide();
            }
        }

        for (Section section : sections) {
            if (section.equals(sectionToShow)) {
                callHandlers(section, true);
            } else {
                callHandlers(section, false);
            }
        }
    }

    private void callHandlers(Section section, Boolean visible) {
        if (handlerMap.get(section) != null) {
            for (ValueChangeHandler<Boolean> handler : handlerMap.get(section)) {
                handler.onValueChange(new SectionVisibilityChangeEvent(visible));
            }
        }
    }

    public void addVisibilityChangeHandlerToSection(Section section, ValueChangeHandler<Boolean> handler) {
        if (handlerMap.get(section) == null) {
            handlerMap.put(section, new ArrayList<ValueChangeHandler<Boolean>>());
        }
        handlerMap.get(section).add(handler);
    }

    public void clearAllHandlers() {
        handlerMap.clear();
    }

    public static class SectionVisibilityChangeEvent extends ValueChangeEvent<Boolean> {

        public SectionVisibilityChangeEvent(Boolean value) {
            super(value);
        }

    }
}
